package com.snb.play.dwebtoon.util;

import java.io.File;
import java.io.FileOutputStream;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.Collator;
import java.util.Collections;
import java.util.Comparator;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONObject;

import android.app.Service;
import android.net.http.AndroidHttpClient;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;

import com.snb.play.dwebtoon.ContentListActivity;
import com.snb.play.dwebtoon.R;
import com.snb.play.dwebtoon.data.DTO_EpisodeImage;
import com.snb.play.dwebtoon.data.DTO_EpisodeToon;
import com.snb.play.dwebtoon.data.EpData;

public class ToonLoaderTask {
//	public class ToonLoaderTask extends Thread {

	private static String TAG = ToonLoaderTask.class.getSimpleName();
	private DTO_EpisodeToon mEpToon;
	public SharedData mWebToon;
	public static boolean gRunning = false;
	private Service mService;
	private int errCnt = 0;
	private boolean hasError = false;
	private final int MAXERRORCNT = 3;
	private final static Comparator<EpData> myComparator = new Comparator<EpData>() {

		private final Collator collator = Collator.getInstance();

		@Override
		public int compare(EpData object1, EpData object2) {
			int diff = object1.id.length() - object2.id.length();
			String objStr1 = object1.id;
			String objStr2 = object2.id;
			if (diff > 0)
				objStr2 = "0" + object2.id;
			else if (diff < 0)
				objStr1 = "0" + object1.id;

			return collator.compare(objStr1, objStr2);
		}
	};

	public ToonLoaderTask(Service aContext, SharedData aWebToon) {
		this.mWebToon = aWebToon;
		mService = aContext;
		errCnt = 0;
	}

	final int NOTIFINISH = 0;
	final int RELOAD = 1;

	final int HANDLER_DELAY = 100;

	private void notiFinish() {
		NotificationCenter.addNotification(mService.getApplicationContext(), null, Integer.parseInt(mWebToon.mMainId), R.drawable.snb_comic_icon,
				mWebToon.mToonName + "다운로드", mWebToon.mToonName, mWebToon.mToonName + "  다운로드 완료",
				ContentListActivity.getBitmapDrawable(mWebToon.mEpisodes.get(0).thumbUrl), 1, 1);

		((DownloadService) mService).finishToonLoaderTask(mKey);
		if (DBProvider.getInstance() != null)
			DBProvider.getInstance().gDbProvider.dbObj.close();
	}

	public Handler mHandler = new Handler() { // 핸들러 처리부분
		public void handleMessage(Message msg) { // 메시지를 받는부분
			switch (msg.what) { // 메시지 처리
				case NOTIFINISH:
					notiFinish();
					isFinish = true;
					break;
				case 2:
					doInBackground(mKey);
					break;
				case 3:
					break;
			}
		};
	};

	private String mKey;
	Thread mThread;

	protected void doInBackground(final String params) {

		System.gc();
		mKey = params;
		mThread = new Thread(new Runnable() {

			@Override
			public void run() {
				// TODO Auto-generated method stub
				int cnt = 0;

				Collections.sort(ToonLoaderTask.this.mWebToon.mEpisodes, myComparator);

				for (EpData lEps : ToonLoaderTask.this.mWebToon.mEpisodes) {
					cnt++;
					JSONObject lJsonObject = null;

					try {
						System.gc();
						lJsonObject = ((DownloadService) mService).getRest().getDaumWebToonImg(lEps.id);
						mEpToon = new DTO_EpisodeToon(lJsonObject);
						mEpToon.pid = ToonLoaderTask.this.mWebToon.mMainId;

						int maxCnt = mEpToon.images.size();
						int sucCnt = 0;

						for (DTO_EpisodeImage lEpisodeImage : mEpToon.images) {
							lEpisodeImage.pid = mEpToon.id;
							lEpisodeImage.main_id = mEpToon.pid;
							try {
								if (lEpisodeImage.url.indexOf("flv") == -1 && lEpisodeImage.mediaType.indexOf("image") > -1) {
									if (downloadBitmap(lEpisodeImage.url, mWebToon.mMainNickName, lEps.id)) {
										lEpisodeImage.insertObjToDB();
										sucCnt += 1;
									}
								} else {
									sucCnt++;
								}
							} catch (Exception e) {
								hasError = true;
								e.printStackTrace();
							}
						}
						if (sucCnt == maxCnt) {
							try {
								Logger.d(mEpToon.title, mEpToon.viewType);
								mEpToon.insertObjToDB();
								NotificationCenter.addNotification(mService, null, Integer.parseInt(mWebToon.mMainId), R.drawable.snb_comic_icon,
										mWebToon.mMainNickName + "다운로드", lEps.title, lEps.title + "  다운로드 완료",
										ContentListActivity.getBitmapDrawable(lEps.thumbUrl), ToonLoaderTask.this.mWebToon.mEpisodes.size(), cnt);
							} catch (Exception e) {
								hasError = true;

								e.printStackTrace();
							}
						}

					} catch (Exception e) {
						hasError = true;
						e.printStackTrace();

					} finally {

					}

				}
				Message msg = mHandler.obtainMessage();
				if (hasError && errCnt <= MAXERRORCNT) {
					msg.what = RELOAD;
				} else {
					msg.what = NOTIFINISH;
				}
				mHandler.sendMessageDelayed(msg, HANDLER_DELAY);
			}
		});
		mThread.start();
	}

	private synchronized boolean downloadBitmap(String url, String aToonTitle, String aToonId) {
		boolean result = false;

		String lJpgFileName = makeJpgFileNameByUrl(url);
		String path = FileManager.BASEPATH + BinderManager.PKG_NAME + FileManager.TOONSPATH + "/" + aToonTitle + "/" + aToonId;

		String extState = Environment.getExternalStorageState();
		if (extState.equals(Environment.MEDIA_MOUNTED)) {
			File lPath = new File(path);
			if (!lPath.exists())
				lPath.mkdirs();
			File file = new File(path, lJpgFileName);
			if (file.exists())
				return true;

			final HttpClient client = new DefaultHttpClient();
			final HttpGet getRequest = new HttpGet(url);

			try {
				HttpResponse response = client.execute(getRequest);

				final int statusCode = response.getStatusLine().getStatusCode();
				if (statusCode != HttpStatus.SC_OK) {
					Logger.w("ImageDownloader", "Error " + statusCode + " while retrieving bitmap from " + url);
				}

				final HttpEntity entity = response.getEntity();
				if (entity != null) {
					InputStream inputStream = null;
					try {
						Logger.d(TAG, entity.getContentType().getValue());
						inputStream = entity.getContent();

						FileOutputStream fileOutput = new FileOutputStream(file);

						FlushedInputStream fis = new FlushedInputStream(inputStream);
						byte[] buffer = new byte[4096];
						int bufferLength = 0;

						try {

							while ((bufferLength = fis.read(buffer)) > 0) {
								fileOutput.write(buffer, 0, bufferLength);
							}

							fileOutput.flush();
							fileOutput.close();
							result = true;
						} catch (IOException e) {
							e.printStackTrace();
						}

					} catch (Exception e) {

						e.printStackTrace();

					} finally {
						if (inputStream != null) {
							inputStream.close();
						}
						entity.consumeContent();
					}
				}
			} catch (IOException e) {
				getRequest.abort();
				Logger.w(TAG, "I/O error while retrieving bitmap from " + url, e);
			} catch (IllegalStateException e) {
				getRequest.abort();
				Logger.w(TAG, "Incorrect URL: " + url, e);
			} catch (Exception e) {
				getRequest.abort();
				Logger.w(TAG, "Error while retrieving bitmap from " + url, e);
			} finally {
				if ((client instanceof AndroidHttpClient)) {
					((AndroidHttpClient) client).close();
				}
			}
//			if (file.exists())
//				((DownloadService) mService).addFileSize(file.length());
		}
		// Logger.printEndTime("DOWN_TASK");

		return result;
	}

	static class FlushedInputStream extends FilterInputStream {
		public FlushedInputStream(InputStream inputStream) {
			super(inputStream);
		}

		@Override
		public long skip(long n) throws IOException {
			long totalBytesSkipped = 0L;
			while (totalBytesSkipped < n) {
				long bytesSkipped = in.skip(n - totalBytesSkipped);
				if (bytesSkipped == 0L) {
					int b = read();
					if (b < 0) {
						break; // we reached EOF
					} else {
						bytesSkipped = 1; // we read one byte
					}
				}
				totalBytesSkipped += bytesSkipped;
			}
			return totalBytesSkipped;
		}
	}

//	@Override
//	public void run() {
//
//		while (!ToonLoaderTask.currentThread().isInterrupted()) {
//
//		}
//
//	}

	public void calledStop() {
		try {
			if (mThread != null || mThread.isAlive() || !mThread.isInterrupted()) {
				mThread.interrupt();
				mThread = null;
			}
		} catch (Exception e) {

		}
	}

	public static String makeJpgFileNameByUrl(String aUrl) {
		String[] returnStrs = aUrl.split("/");
		return returnStrs[returnStrs.length - 1] + FileManager.JPG;
	}

	public static String makeJustFileNameByUrl(String aUrl) {
		String[] returnStrs = aUrl.split("/");
		return returnStrs[returnStrs.length - 1];
	}

	public static String makeTitFileNameByUrl(String aUrl) {
		String[] returnStrs = aUrl.split("/");
		return returnStrs[returnStrs.length - 1] + FileManager.TIMG;
	}

	private boolean isFinish = false;

	@Override
	protected void finalize() throws Throwable {
		// TODO Auto-generated method stub
		Message msg = mHandler.obtainMessage();
		if (isFinish) {
			msg.what = NOTIFINISH;
			mHandler.sendMessageDelayed(msg, HANDLER_DELAY);
			super.finalize();
		} else {

			msg.what = RELOAD;
			mHandler.sendMessageDelayed(msg, HANDLER_DELAY);
			return;
		}

	}
}
